package com.sj.interceptor;

import cn.hutool.json.JSONUtil;
import com.sj.common.bean.LocalUser;
import com.sj.common.lang.ApiResult;
import com.sj.common.lang.ResultInfo;
import com.sj.entity.User;
import com.sj.service.UserService;
import com.sj.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

/**
 * Created with IntelliJ IDEA.
 * User: xiaoqi
 * Date: 2022-03-10
 * Time: 下午 13:39
 * Description: 权限拦截器
 *
 * @author xiaoqi
 * @since 2022-03-10
 */
public class PermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Optional<AuthCheck> authCheck = this.getAuthCheck(handler);
        // 如果没有 AuthCheck修饰就直接放行
        if (!authCheck.isPresent()) {
            return true;
        }

        // 检查token是否正确
        Claims claims = jwtUtils.checkToken(request);

        if (claims != null) {
            String sub = claims.getSubject();
            User user = userService.getById(Integer.parseInt(sub.split("-")[0]));
            if (user != null) {
                LocalUser.set(user);
            }else{
                ServletOutputStream outputStream = response.getOutputStream();
                outputStream.write(JSONUtil.toJsonStr(ApiResult.error(ResultInfo.NO_LOGIN)).getBytes("UTF-8"));
                outputStream.flush();
                outputStream.close();
            }
            return user != null;
        }
        return false;
    }

    private Optional<AuthCheck> getAuthCheck(Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 判断方法有没有AuthCheck注解
            AuthCheck authCheck = handlerMethod.getMethod().getAnnotation(AuthCheck.class);
            if (authCheck == null) {
                return Optional.empty();
            }
            return Optional.of(authCheck);
        }
        return Optional.empty();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LocalUser.clear();
    }
}